package com.mingtu.dzpatrol.fragment;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;

import com.adam.gpsstatus.GpsStatusProxy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.AMapLocationQualityReport;
import com.amap.api.location.DPoint;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.PolygonOptions;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SPStaticUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.hjq.gson.factory.GsonFactory;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.interfaces.OnConfirmListener;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.model.Response;
import com.mingtu.dzpatrol.R;
import com.mingtu.dzpatrol.activity.NewPreviewActivity;
import com.mingtu.dzpatrol.base.BaseApplication;
import com.mingtu.dzpatrol.base.BaseFragment;
import com.mingtu.dzpatrol.bean.AreaBean;
import com.mingtu.dzpatrol.bean.VideoListBean2;
import com.mingtu.dzpatrol.callback.ResultCallback;
import com.mingtu.dzpatrol.callback.StringDialogCallback;
import com.mingtu.dzpatrol.utils.ActivityUtil;
import com.mingtu.dzpatrol.utils.Constant;
import com.mingtu.dzpatrol.utils.IntentUtils;
import com.mingtu.dzpatrol.utils.MarkerOptionsUtils;
import com.mingtu.dzpatrol.utils.MyLogUtil;
import com.mingtu.dzpatrol.utils.MyUtills;
import com.mingtu.dzpatrol.utils.PathSmoothTool;
import com.mingtu.dzpatrol.utils.SPTools;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;

import static com.mingtu.dzpatrol.utils.Constant.INFO_WINDOW_OFF_SET_Y;
import static com.mingtu.dzpatrol.utils.MyUtills.getBounds;

public class Tab2Fragment extends BaseFragment implements LocationSource, AMapLocationListener, AMap.OnMarkerClickListener,
        AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener, AMap.OnMapTouchListener {

    @BindView(R.id.iv_location)
    ImageView ivLocation;
    @BindView(R.id.iv_mode)
    ImageView ivMode;
    private MapView mapView;
    private AMap aMap;
    private MyLocationStyle myLocationStyle;
    private int locationNum = 0;
    private OnLocationChangedListener mListener;
    private AMapLocationClient locationClient;
    private long locationTime;
    private LatLng location;
    private AMapLocation myAMapLocation;
    private HashMap<String, Object> locationHashMap;
    private PathSmoothTool mpathSmoothTool;
    private boolean isSports = false;
    private GpsStatusProxy proxy;
    private LocationManager locationManager;
    private SensorManager sensorManager;
    private boolean netWorkState = true;
    private boolean satelliteMap = true;
    private List<LatLng> areaAllLatLng;
    private List<Marker> markerList = new ArrayList<>();
    private View infoWindow;
    private Marker clickMarker;

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        mapView = view.findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_tab2;
    }

    @Override
    protected void initData() {
        initMap();
    }

    @Override
    protected void initView(View view) {

    }

    @Override
    protected void getData() {

    }

    @Override
    public void onDestroy() {
        //销毁时，需要销毁定位client
        if (null != locationClient) {
            locationClient.stopLocation();
            locationClient.onDestroy();
        }


        deactivate();

        if (proxy != null) {
            if (locationManager != null) {
                locationManager.removeUpdates(myLocationListener);
            }
            proxy.unRegister();
        }


        if (sensorManager != null) {
            sensorManager.unregisterListener(new MySensorEventListener());
        }

        //销毁地图对象,在此方法之后代码将不再执行
        if (aMap != null) {
            mapView.onDestroy();
            aMap.clear();
        }
        super.onDestroy();
    }

    @OnClick({R.id.iv_location, R.id.iv_mode})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.iv_location:
                locationManagerEvent(null);
                break;
            case R.id.iv_mode:
                if (satelliteMap) {
                    setMapType(0);
                    satelliteMap = false;
                } else {
                    setMapType(1);
                    satelliteMap = true;
                }
                break;
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == Constant.REQUEST_CODE_TWO) {
            //从定位设置界面返回
            try {
                boolean gpsState = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                if (gpsState) {
                    if (myAMapLocation != null && mListener != null && location == null) { //防止点击定位按钮的时候不出现小蓝点
                        mListener.onLocationChanged(myAMapLocation);// 显示系统小蓝点
                        aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
                    } else {
                        aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (requestCode == XXPermissions.REQUEST_CODE) {
            if (XXPermissions.isGranted(getActivity(), Permission.ACCESS_COARSE_LOCATION) || XXPermissions.isGranted(getActivity(), Permission.ACCESS_FINE_LOCATION)) {
                initGpsStatus();
            } else {
                ToastUtils.showLong("GPS权限获取失败");
            }
        }


    }


    /**
     * 初始化地图
     */
    private void initMap() {
        aMap = mapView.getMap();
        aMap.setLocationSource(this);// 设置定位监听
        //地图模式可选类型：MAP_TYPE_NORMAL,MAP_TYPE_SATELLITE,MAP_TYPE_NIGHT
        aMap.setMapType(AMap.MAP_TYPE_SATELLITE);// 卫星地图模式
        aMap.getUiSettings().setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示
        aMap.getUiSettings().setZoomControlsEnabled(false);
//        aMap.setMaxZoomLevel(MAX_ZOOM);
        myLocationStyle = new MyLocationStyle();
//        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点，定位点依照设备方向旋转，并且蓝点会跟随设备移动。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点，定位点依照设备方向旋转，并且蓝点会跟随设备移动。

        // 自定义定位蓝点图标
        myLocationStyle.myLocationIcon(
                BitmapDescriptorFactory.fromResource(R.mipmap.gps_point));
        // 自定义精度范围的圆形边框颜色
        myLocationStyle.strokeColor(Color.argb(100, 47, 185, 97));
        // 自定义精度范围的圆形边框宽度
        myLocationStyle.strokeWidth(0.1F);
        // 设置圆形的填充颜色
        myLocationStyle.radiusFillColor(Color.argb(100, 47, 185, 97));
        // 将自定义的 myLocationStyle 对象添加到地图上
        aMap.setMyLocationStyle(myLocationStyle);
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        // 设置定位的类型为定位模式 ，可以由定位、跟随或地图根据面向方向旋转几种
//        aMap.setMyLocationType(AMap.LOCATION_TYPE_MAP_FOLLOW);
        aMap.moveCamera(CameraUpdateFactory.zoomTo(Constant.MAP_ZOOM));
        aMap.setOnMarkerClickListener(this);
        aMap.setInfoWindowAdapter(this);
        aMap.addOnMapTouchListener(this);
        aMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
            @Override
            public void onMapLoaded() {
                getAreaData();
                getDequiList();
            }
        });

        mpathSmoothTool = new PathSmoothTool();
        mpathSmoothTool.setIntensity(Constant.Intensity);
        mpathSmoothTool.setThreshhold(0);

        //传感器
        sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
        Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
        sensorManager.registerListener(new MySensorEventListener(), sensor, SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void locationPermissions() {
        //为了适配android11，这个权限单独申请。如果申请的权限中包含后台定位权限， 那么这里面则不能包含和定位无关的权限，否则框架会抛出异常，
        // 因为 ACCESS_BACKGROUND_LOCATION 和其他非定位权限定位掺和在一起申请，在 Android 11 上会出现不申请直接被拒绝的情况。
        //也就是说，如果你想获得后台定位权限，必须弹窗两次：
        //第一次，申请普通定位权限的弹窗。
        //第二次，在用户同意了普通定位权限之后，申请 后台定位权限时弹窗。
        //这里也要千万注意，在没有拿到 普通定位权限的时候，直接申请后台定位权限，将不弹窗直接授权失败。
        XXPermissions.with(this)
                .permission(Permission.ACCESS_COARSE_LOCATION)
                .permission(Permission.ACCESS_FINE_LOCATION)
//                .permission(Permission.NOTIFICATION_SERVICE)
//                .permission(Permission.Group.STORAGE)
                .request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(List<String> permissions, boolean all) {
                        if (permissions.contains(Permission.ACCESS_COARSE_LOCATION) ||
                                permissions.contains(Permission.ACCESS_FINE_LOCATION)) {
                            initGpsStatus();
                            if (myAMapLocation != null && mListener != null) { //防止点击定位按钮的时候不出现小蓝点
                                mListener.onLocationChanged(myAMapLocation);// 显示系统小蓝点
                                aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
                            } else {
                                aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
                            }
                        }
                    }

                    @Override
                    public void onDenied(List<String> permissions, boolean never) {
                        if (never) {
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
                            new XPopup.Builder(getActivity())
                                    .isDestroyOnDismiss(true)
                                    .dismissOnTouchOutside(true)
                                    .hasShadowBg(true)
                                    .asConfirm(context.getResources().getString(R.string.text_tip), context.getResources().getString(R.string.text_location_storage_auth),
                                            context.getResources().getString(R.string.text_cancle), context.getResources().getString(R.string.text_sure),
                                            new OnConfirmListener() {
                                                @Override
                                                public void onConfirm() {
                                                    XXPermissions.startPermissionActivity(Tab2Fragment.this, permissions);
                                                }
                                            }, null, false)
                                    .show();
                        } else {

                        }

                    }
                });
    }

    public void setNetWorkState(boolean netWorkState) {
        this.netWorkState = netWorkState;
    }

    public void setMapType(int type) {
        switch (type) {
            case 0:
                aMap.setMapType(AMap.MAP_TYPE_NORMAL);// 矢量地图模式
                break;
            case 1:
                aMap.setMapType(AMap.MAP_TYPE_SATELLITE);// 卫星地图模式
                break;
        }

    }

    /**
     * 区域范围
     */
    private void getAreaData() {
        OkGo.<String>get(Constant.GET_AREA)
                .tag(this)
                .cacheMode(CacheMode.REQUEST_FAILED_READ_CACHE)
                .execute(new StringDialogCallback(getActivity()) {
                    @Override
                    public void onSuccess(Response<String> response) {
                        getAreaDataCommon(response);
                    }

                    @Override
                    public void onCacheSuccess(Response<String> response) {
                        super.onCacheSuccess(response);
                        getAreaDataCommon(response);
                    }

                    @Override
                    public void onError(Response<String> response) {
                        String result = response.body();
                        MyLogUtil.e(getClass().getSimpleName(), "onError==" + result);

                    }
                });
    }

    private void getAreaDataCommon(Response<String> response) {
        String result = response.body();
        if (!StringUtils.isEmpty(result)) {
            AreaBean areaBean = null;
            try {
                Gson gson = GsonFactory.getSingletonGson();
                areaBean = new AreaBean();
                areaBean = gson.fromJson(result, AreaBean.class);

                List<AreaBean.FeaturesBean> featuresBeans = areaBean.getFeatures();
                List<List<LatLng>> areaLatLngList = new ArrayList<>(); //存放所有区域的数据
                areaAllLatLng = new ArrayList<>();
                for (int i = 0; i < featuresBeans.size(); i++) {
                    AreaBean.FeaturesBean featuresBean = featuresBeans.get(i);
                    AreaBean.FeaturesBean.PropertiesBeanX propertiesBeanX = featuresBean.getProperties();
                    AreaBean.FeaturesBean.GeometryBean geometryBean = featuresBean.getGeometry();
                    List<List<List<List<Double>>>> coordinates = geometryBean.getCoordinates();
                    List<List<Double>> myList = coordinates.get(0).get(0);
                    List<DPoint> geoFencePoints = new ArrayList<DPoint>();  //存放地里围栏需要的数据
                    List<LatLng> latLngs = new ArrayList<>();//存放单条区域的数据
                    for (int j = 0; j < myList.size(); j++) {
                        List<Double> latLngList = myList.get(j);
                        double gpsLat = latLngList.get(1);
                        double gpsLng = latLngList.get(0);
                        //gps 转高德的经纬度
//                                        double[] latlngs = GPSTransToAMap.transform(gpsLat, gpsLng);
//                                        LatLng latLng = new LatLng(latlngs[0], latlngs[1]);
//                                        points.add(new DPoint(latlngs[0], latlngs[1]));

                        LatLng latLng = new LatLng(gpsLat, gpsLng);
                        latLngs.add(latLng); //将坐标装到数组里
                        geoFencePoints.add(new DPoint(gpsLat, gpsLng));
                        areaAllLatLng.add(latLng);

                    }

                    PolygonOptions polygonOptions = new PolygonOptions();
                    polygonOptions.addAll(latLngs);
                    polygonOptions.strokeWidth(5f);
                    polygonOptions.zIndex(45);
                    String gnfy = propertiesBeanX.getGnfq();
                    if (isAdded()) { //避免出现Fragment  not attached to Activity
                        switch (gnfy) {
                            case "实验区":
                                polygonOptions.fillColor(context.getResources().getColor(R.color.bg_color_00f2));
                                polygonOptions.strokeColor(context.getResources().getColor(R.color.bg_color_00f));
                                break;
                            case "缓冲区":
                                polygonOptions.fillColor(context.getResources().getColor(R.color.bg_color_fff2));
                                polygonOptions.strokeColor(context.getResources().getColor(R.color.bg_color_ecd));
                                break;
                            case "核心区":
                                polygonOptions.fillColor(context.getResources().getColor(R.color.bg_color_ff02));
                                polygonOptions.strokeColor(context.getResources().getColor(R.color.bg_color_f44));
                                break;
                        }
                    }

                    aMap.addPolygon(polygonOptions);
                    areaLatLngList.add(latLngs);

                }

                if (areaAllLatLng.size() > 0) {
                    aMap.moveCamera(CameraUpdateFactory.newLatLngBounds(getBounds(areaAllLatLng), 200));
                }

            } catch (JsonSyntaxException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 设备信息
     */
    private void getDequiList() {
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("curPage", 1);
        hashMap.put("pageSize", 300);
        String str = GsonUtils.toJson(hashMap);
        OkGo.<String>post(Constant.getInstance().POST_CAMERA_LIST)
                .tag(this)
                .upJson(str)
                .execute(new StringDialogCallback(getActivity()) {
                    @Override
                    public void onSuccess(Response<String> response) {
                        String result = response.body();
                        if (!StringUtils.isEmpty(result)) {

                            VideoListBean2 videoListBean = null;
                            Gson gson = GsonFactory.getSingletonGson();
                            videoListBean = new VideoListBean2();
                            videoListBean = gson.fromJson(result, VideoListBean2.class);
                            List<VideoListBean2.PageBean.ListBean> dataBeans = videoListBean.getPage().getList();

                            if (dataBeans != null) {
                                int size = dataBeans.size();
                                if (size > 0) {
                                    ArrayList<BitmapDescriptor> cameraBayonetGif = new ArrayList<BitmapDescriptor>();
                                    ApplicationInfo appInfo2 = context.getApplicationInfo();
                                    for (int i = 1; i <= 24; i++) {
                                        int resID = getResources().getIdentifier("icon_camera_bayonet" + i, "mipmap", appInfo2.packageName);
                                        cameraBayonetGif.add(BitmapDescriptorFactory.fromResource(resID));
                                    }

                                    List<LatLng> latLngs = new ArrayList<>();

                                    for (int i = 0; i < size; i++) {
                                        VideoListBean2.PageBean.ListBean listBean = dataBeans.get(i);
                                        String latitude = listBean.getLat();
                                        String longitude = listBean.getLng();
                                        String status = listBean.getStatus();
                                        String name = listBean.getName();
                                        String code = listBean.getCode();

                                        if (StringUtils.isEmpty(status)) {
                                            status = "1"; //为空的话 暂时赋值为离线状态
                                        }

                                        //过滤掉经纬度为空的数据
                                        if (!StringUtils.isEmpty(latitude) && !StringUtils.isEmpty(longitude)) {
                                            double lat = Double.parseDouble(latitude);
                                            double lng = Double.parseDouble(longitude);
                                            LatLng location = new LatLng(lat, lng);

                                            HashMap<String, Object> myHashMap = new HashMap<>();
                                            myHashMap.put("cameraName", name);
                                            myHashMap.put("code", code);
                                            String cameraInfo = GsonUtils.toJson(myHashMap);

                                            //添加Marker
                                            if (status.equals("0")) {
                                                Marker marker2 = aMap.addMarker(MarkerOptionsUtils.getMarkerOptions2(location, cameraInfo, INFO_WINDOW_OFF_SET_Y, cameraBayonetGif));
                                                markerList.add(marker2);
                                                latLngs.add(location);

                                            } else if (status.equals("1")) {
                                                Marker marker22 = aMap.addMarker(MarkerOptionsUtils.getMarkerOptions1(location, cameraInfo, INFO_WINDOW_OFF_SET_Y, R.mipmap.icon_camera_bayonet_offline));
                                                markerList.add(marker22);
                                                latLngs.add(location);
                                            }

                                        }

//                                        if (latLngs.size() > 0) {
//                                            aMap.moveCamera(CameraUpdateFactory.newLatLngBounds(getBounds(latLngs), 300));
//                                        }
                                    }


                                }
                            }
                        }
                    }
                });
    }

    /******定位相关逻辑******/

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        //errCode等于0代表定位成功，其他的为定位失败，具体的可以参照官网定位错误码说明
        if (mListener != null && aMapLocation != null) {
            if (aMapLocation != null && aMapLocation.getErrorCode() == 0) {
                locationNum++;
                double longitude = aMapLocation.getLongitude();
                double latitude = aMapLocation.getLatitude();
                locationTime = aMapLocation.getTime();
                float speed = aMapLocation.getSpeed();
                float bearing = aMapLocation.getBearing();
                float accuracy = aMapLocation.getAccuracy();
                location = new LatLng(latitude, longitude);
                //定位的时候用
                myAMapLocation = aMapLocation;

                if (locationNum == 1) {
                    //第一次定位将地图移动到蓝点
//                    aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
                    mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点
                }

                String address = aMapLocation.getAddress();//地址，如果option中设置isNeedAddress为false，则没有此结果，网络定位结果中会有地址信息，GPS定位不返回地址信息。
                String province = aMapLocation.getProvince();//省信息
                String city = aMapLocation.getCity();//城市信息
                String district = aMapLocation.getDistrict();//城区信息
                String street = aMapLocation.getStreet();//街道信息
                String aoiName = aMapLocation.getAoiName();//定位点信息
                String description = aMapLocation.getDescription();

                String detailsAddress = province + city + district + street + aoiName;

                if (StringUtils.isEmpty(aoiName)) {
                    detailsAddress = address;
                    aoiName = description;
                }

                SPStaticUtils.put(SPTools.aoiName, aoiName);
                SPStaticUtils.put(SPTools.address, detailsAddress);
                SPStaticUtils.put(SPTools.lat, latitude + "");
                SPStaticUtils.put(SPTools.lng, longitude + "");
                SPStaticUtils.put(SPTools.city, city);

                //有时候会返回(0，0)点需要排除
                if (latitude == 0f || longitude <= 0.001f) {
                    return;
                }


                if (locationHashMap != null) {
                    //不等于空的时候将存的点取出来，与当前点进行对比，如果距离小于3米就不进行存储
                    List<LatLng> doublePointLatLngs = new ArrayList<>();
                    LatLng storageLocation = (LatLng) locationHashMap.get("location");
                    long storageLocationTime = (long) locationHashMap.get("locationTime");
                    doublePointLatLngs.add(storageLocation);
                    doublePointLatLngs.add(location);
                    //计算距离
                    float distance = MyUtills.getDistance(doublePointLatLngs);

                    //计算速度
                    long timeDev = (locationTime - storageLocationTime) / 1000; //两个点的时间差值,单位秒
                    float mySpeed = distance / (int) timeDev;


                    locationHashMap.put("location", location);
                    locationHashMap.put("locationTime", locationTime);

                    // 正常行走、跑步、骑行速度不会超过5m/s,
                    // 先判断物体是否移动，timeDev == 0或者speed == 0说明物体没有移动，不为0说明物体在移动，
                    // 移动的时候分为匀速移动和非匀速移动，此过程中都有可能发生漂移的情况，物体发生移动，判断物体速度，根据mySpeed 和 speed 差值 判断是否发生漂移

                    if (timeDev == 0) { //时间间隔为0或者speed为0，说明物体未移动
                        return;
                    }

                    if (Float.isNaN(mySpeed)) {
                        return;
                    }


                    if (mySpeed > 40) { //移动太快，是漂移情况
                        return;
                    }
                    //此处isSports==false为匀速运动或者静止，isSports==true为非匀速运动(步行或者骑行),所以此值不做判断依据
                    //物体在非匀速移动,速度差值mySpeed和 speed 速度相近，根据差值绝对值判断否则为漂移
                    float speedDev = Math.abs(mySpeed - speed);
                    if (speedDev > 1.5) {
                        return;
                    }

                    if (!isSports) {
                        if (mySpeed < 1.25) {
                            return;
                        }
                    }


                    LatLng kalmanFilterPoint = mpathSmoothTool.kalmanFilterPoint(storageLocation, location); //单点滤波
                    location = kalmanFilterPoint;
                    aMapLocation.setLatitude(kalmanFilterPoint.latitude);
                    aMapLocation.setLongitude(kalmanFilterPoint.longitude);

//                    locationHashMap.put("location", location); //此处代码和上面的上面的不重复,保存滤波后的数据，但是此处代码会造成计算速度和实际的速度不符
//                    locationHashMap.put("locationTime", locationTime);

                    mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点

                } else {

                    locationHashMap = new HashMap<>();
                    locationHashMap.put("location", location);
                    locationHashMap.put("locationTime", locationTime);
                    mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点
                }

            } else {
                //定位失败
                StringBuffer sb1 = new StringBuffer();
                sb1.append("定位失败" + "\n");
                sb1.append("错误码:" + aMapLocation.getErrorCode() + "\n");
                sb1.append("错误信息:" + aMapLocation.getErrorInfo() + "\n");
                sb1.append("错误描述:" + aMapLocation.getLocationDetail() + "\n");
                LogUtils.e("loaction", sb1.toString());

                StringBuffer sb2 = new StringBuffer();
                sb1.append("定位失败" + "\n");
                sb2.append("* WIFI开关：").append(aMapLocation.getLocationQualityReport().isWifiAble() ? "开启" : "关闭").append("\n");
                sb2.append("* GPS状态：").append(getGPSStatusString(aMapLocation.getLocationQualityReport().getGPSStatus())).append("\n");
//            if (!netStatus) {
//                ToastUtils.showLong("网络未连接，" + getGPSStatusString(aMapLocation.getLocationQualityReport().getGPSStatus()));
//            }


                LogUtils.e("loaction", sb2.toString());
                if (locationNum == 1 && SPStaticUtils.contains(SPTools.token)) {
                    ToastUtils.showLong(sb2.toString());
                }
            }
        }
    }

    /**
     * 激活定位
     *
     * @param listener
     */
    @Override
    public void activate(OnLocationChangedListener listener) {
        mListener = listener;
        if (locationClient == null) {
            try {
                AMapLocationClient.updatePrivacyShow(context, true, true);
                AMapLocationClient.updatePrivacyAgree(context, true);
                locationClient = new AMapLocationClient(BaseApplication.getContext());
                AMapLocationClientOption option = new AMapLocationClientOption();
                //设置定位监听
                //设置为高精度定位模式
                option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
                //设获取高精度模式下单次定位是否优先返回卫星定位信息,只有在单次定位高精度定位模式下有效
                //为true时，会等待卫星定位结果返回，最多等待30秒，若30秒后仍无卫星定位结果返回，返回网络定位结果
                option.setGpsFirst(true);
                option.setGpsFirstTimeout(5 * 1000);
                //option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Device_Sensors);
                //定位场景
                option.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.Sport);
                //设置定位间隔,单位毫秒,默认为2000ms，最低1000ms。
                option.setInterval(Constant.LOCATION_INTERVAL_TIME);
                //自3.1.0版本开始，不限定定位类型，当定位类型不是AMapLocation.LOCATION_TYPE_GPS时，可以通过 AMapLocationClientOption.setSensorEnable(boolean) 控制是否返回速度值，当设置为true时会通过手机传感器获取速度,如果手机没有对应的传感器会返回0.0
                option.setSensorEnable(true);
                //设置定位参数
                locationClient.setLocationOption(option);
                locationClient.disableBackgroundLocation(true);
//                locationClient.enableBackgroundLocation(NotificationUtils.NOTIFY_ID, NotificationUtils.buildNotification(BaseApplication.getContext()));
                // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
                // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
                // 在定位结束后，在合适的生命周期调用onDestroy()方法
                // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
                locationClient.startLocation();
                locationClient.setLocationListener(this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void deactivate() {
        mListener = null;
        if (locationClient != null) {
            locationClient.stopLocation();
        }
    }

    @Override
    public View getInfoWindow(Marker marker) {
        //关闭了点击事件，此处逻辑没有展示效果
        if (infoWindow == null) {
            infoWindow = LayoutInflater.from(getActivity()).inflate(R.layout.bubble_view2, null);
        }

        List<LatLng> latLngs = new ArrayList<>();
        LatLng latLng = marker.getPosition();
        latLngs.add(latLng);
        latLngs.add(location);
        float distance = MyUtills.getDistance(latLngs);
        if (distance < 1) {
            return null;
        }
        render(marker, infoWindow);
        return infoWindow;

    }

    @Override
    public View getInfoContents(Marker marker) {
        return null;
    }

    @Override
    public void onInfoWindowClick(Marker marker) {
        marker.hideInfoWindow();
    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        marker.showInfoWindow();
        clickMarker = marker;
        return false;
    }

    @Override
    public void onTouch(MotionEvent motionEvent) {
        if (clickMarker != null) {
            boolean b = clickMarker.isInfoWindowShown();
            if (b) {
                clickMarker.hideInfoWindow();
            }
        }
    }

    /**
     * 自定义infowinfow窗口
     */
    public void render(Marker marker, View view) {
        String cameraInfo = marker.getTitle();
        TextView title = ((TextView) view.findViewById(R.id.title));

        JSONObject jsonObject = JSON.parseObject(cameraInfo);
        String code = jsonObject.getString("code");
        String cameraName = jsonObject.getString("cameraName");
        title.setText(cameraName);

        LinearLayout layoutMarker = (LinearLayout) view.findViewById(R.id.layout);
        layoutMarker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //防止点击事件和touch事件冲突，所以采用此种方式跳转
                marker.hideInfoWindow();
                getRtspUrl(code, cameraName);
            }
        });


    }

    /**
     * 根据视频监控编号查询rstp地址
     */
    private void getRtspUrl(String code, String title) {
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("code", code);
        String str = GsonUtils.toJson(hashMap);
        OkGo.<String>post(Constant.getInstance().POST_PREVIEW_URL)
                .tag(this)
                .upJson(str)
                .execute(new StringDialogCallback(getActivity()) {
                    @Override
                    public void onSuccess(Response<String> response) {
                        String result = response.body();//{"msg":"success","code":0,"status":"rtsp://123.7.84.20:554/openUrl/9M1VWDu"}
                        if (!StringUtils.isEmpty(result)) {
                            JSONObject jsonObject = JSON.parseObject(result);
                            String msg = jsonObject.getString("msg");
                            if (msg.equals("success")) {
                                String vodeoUrl = jsonObject.getString("status");
                                if (StringUtils.isEmpty(vodeoUrl)) {
                                    ToastUtils.showLong("未获取到视频链接！");
                                    return;
                                }
                                Bundle bundle = new Bundle();
                                bundle.putString("videoUrl", vodeoUrl);
                                bundle.putString("title", title);
                                bundle.putString("code", code);
                                IntentUtils.getInstance().readyGo(ActivityUtil.getTopActivity(), NewPreviewActivity.class, bundle);

                            }
                        }
                    }

                    @Override
                    public void onError(Response<String> response) {
                        String result = response.body();
                        MyLogUtil.e(getClass().getSimpleName(), "onError==" + result);

                    }
                });
    }


    private void locationManagerEvent(ResultCallback resultCallback) {
        if (locationManager != null) {

            boolean gpsState = false;
            try {
                gpsState = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            } catch (Exception e) {
                ToastUtils.showLong("未获取到GPS定位权限");
                e.printStackTrace();
            }

            if (!netWorkState && !gpsState) {
                ToastUtils.showLong("请打开GPS和数据网络");
            } else {
                if (!gpsState) {
                    new XPopup.Builder(getActivity())
                            .isDestroyOnDismiss(true)
                            .dismissOnTouchOutside(false)
                            .hasShadowBg(true)
                            .asConfirm(context.getResources().getString(R.string.text_tip), "请打开GPS设置",
                                    context.getResources().getString(R.string.text_cancle), context.getResources().getString(R.string.text_sure),
                                    new OnConfirmListener() {
                                        @Override
                                        public void onConfirm() {
                                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                            startActivityForResult(intent, Constant.REQUEST_CODE_TWO);
                                        }
                                    }, null, false)
                            .show();
                }
            }

            if (myAMapLocation != null && mListener != null && location == null) { //防止点击定位按钮的时候不出现小蓝点
                mListener.onLocationChanged(myAMapLocation);// 显示系统小蓝点
                aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
            } else {
                aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
            }
            aMap.moveCamera(CameraUpdateFactory.zoomTo(Constant.MAP_ZOOM));

            if (resultCallback != null) {
                resultCallback.result(gpsState);
            }
        } else {
            new XPopup.Builder(getActivity())
                    .isDestroyOnDismiss(true)
                    .dismissOnTouchOutside(true)
                    .hasShadowBg(true)
                    .asConfirm(context.getResources().getString(R.string.text_tip), context.getResources().getString(R.string.text_location_auth),
                            context.getResources().getString(R.string.text_cancle), context.getResources().getString(R.string.text_sure),
                            new OnConfirmListener() {
                                @Override
                                public void onConfirm() {
                                    List<String> permissions = new ArrayList<>();
                                    permissions.add(Permission.ACCESS_COARSE_LOCATION);
                                    permissions.add(Permission.ACCESS_FINE_LOCATION);
                                    XXPermissions.startPermissionActivity(Tab2Fragment.this, permissions);
                                }
                            }, null, false)
                    .show();
        }
    }


    /**
     * 初始化GPS状态相关
     */
    public void initGpsStatus() {
//        XXPermissions.with(this)
//                .permission(Permission.ACCESS_BACKGROUND_LOCATION)
//                .request(new OnPermissionCallback() {
//                    @Override
//                    public void onGranted(List<String> permissions, boolean all) {
//                        LogUtils.e("testest", "all===" + all);
//                    }
//
//                    @Override
//                    public void onDenied(List<String> permissions, boolean never) {
//                        LogUtils.e("testest", "never===" + never);
//                    }
//                });

        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        try {
            proxy = GpsStatusProxy.getInstance(getActivity().getApplicationContext());
            proxy.register();
            locationManager = (LocationManager) BaseApplication.getBaseApplication().getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, Constant.LOCATION_INTERVAL_TIME, 1, myLocationListener);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private LocationListener myLocationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            proxy.notifyLocation(location);
        }

        @Override
        public void onStatusChanged(String s, int i, Bundle bundle) {

        }

        @Override
        public void onProviderEnabled(String s) {

        }

        @Override
        public void onProviderDisabled(String s) {

        }
    };

    /**
     * 获取GPS状态的字符串
     *
     * @param statusCode GPS状态码
     * @return
     */
    private String getGPSStatusString(int statusCode) {
        String str = "";
        switch (statusCode) {
            case AMapLocationQualityReport.GPS_STATUS_OK:
                str = "GPS状态正常";
                break;
            case AMapLocationQualityReport.GPS_STATUS_NOGPSPROVIDER:
                str = "手机中没有GPS Provider，无法进行GPS定位";
                break;
            case AMapLocationQualityReport.GPS_STATUS_OFF:
                str = "GPS关闭，建议开启GPS，提高定位质量";
                break;
            case AMapLocationQualityReport.GPS_STATUS_MODE_SAVING:
                str = "选择的定位模式中不包含GPS定位，建议选择包含GPS定位的模式，提高定位质量";
                break;
            case AMapLocationQualityReport.GPS_STATUS_NOGPSPERMISSION:
                str = "没有GPS定位权限，建议开启gps定位权限";
                break;
        }
        return str;
    }


    /******传感器******/
    private class MySensorEventListener implements SensorEventListener {

        @Override
        public void onSensorChanged(SensorEvent event) {
//            MyLogUtil.e("sensorManager", "onSensorChanged====\n" + event.values[0] + "\n,1 ==" + event.values[1] + "\n,2==" + event.values[2]);
            if (event == null || event.values == null || event.values.length <= 0) {
                isSports = false;
                return;
            }
            float xValue = event.values[0];
            float yValue = event.values[1];
            float zValue = event.values[2];
            List<Float> sensorValues = new ArrayList<>();
            sensorValues.add(Math.abs(xValue));
            sensorValues.add(Math.abs(yValue));
            sensorValues.add(Math.abs(zValue));

            if (Math.abs(xValue) > 1 || Math.abs(yValue) > 1 || Math.abs(zValue) > 1) { // x 、y、z y有任何一个方向的加速度的绝对值超过1， 说明设备在运动
                isSports = true;
            } else {
                isSports = false;
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int i) {

        }
    }
}